package com.reservation.interceptor;


import com.reservation.constant.JwtClaimsConstant;
import com.reservation.entity.Users;
import com.reservation.mapper.AuthMapper;
import com.reservation.properties.JwtProperties;
import com.reservation.utils.CurrentHolderUtil;
import com.reservation.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;


/**
 * jwt令牌校验的拦截器
 */
@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {    @Autowired
    private JwtProperties jwtProperties;
    
    @Autowired
    private AuthMapper authMapper;


    /**
     * 在请求处理之前进行拦截
     * @param request 请求对象
     * @param response 响应对象
     * @param handler 处理器
     * @return true表示放行，false表示拦截
     * @throws Exception 异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 记录当前请求的URI，用于调试
        String uri = request.getRequestURI();
        log.info("当前请求URI: {}", uri);

        // 获取请求头中的token
        String token = request.getHeader(jwtProperties.getAuthTokenName());
        log.info("请求头中的token: {}", token);
        log.info("验证JWT使用的secretKey: {}", jwtProperties.getAuthSecretKey());

        // 如果是OPTIONS请求，直接放行
        if(request.getMethod().equals("OPTIONS")) {
            return true;
        }

        // 判断是否是不需要验证的路径，图片、静态资源等
        if(uri.contains("/login") || uri.contains("/register") || uri.contains("/public")
                || uri.contains("/images") || uri.contains(".jpg") || uri.contains(".png")
                || uri.contains(".jpeg") || uri.contains(".gif") || uri.startsWith("/server/images/")
                || uri.equals("/favicon.ico")) {
            log.info("不需要验证的路径，直接放行: {}", uri);
            return true;
        }

        // 验证token
        if(token != null && !token.isEmpty()) {
            try {
                // 验证token是否有效
                boolean result = JwtUtil.checkToken(jwtProperties.getAuthSecretKey(), token);
                if(result) {
                    log.info("Token验证成功");
                    Claims claims = JwtUtil.parseJWT(jwtProperties.getAuthSecretKey(),token);
                    Integer authID = claims.get(JwtClaimsConstant.AUTH_ID, Integer.class);
                    log.info("当前用户ID: {}", authID);
                    String authRole = claims.get(JwtClaimsConstant.AUTH_ROLE, String.class);
                    log.info("当前用户角色: {}", authRole);
                    
                    // 检查用户当前状态 - 确保用户没有被冻结或删除
                    Users currentUser = authMapper.getById(authID.longValue());
                    if (currentUser == null) {
                        log.warn("用户ID {} 不存在", authID);
                        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                        return false;
                    }
                    
                    // 检查用户是否被冻结或删除
                    if (currentUser.getStatus() == 2) {
                        log.warn("用户ID {} 已被冻结，拒绝访问", authID);
                        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                        return false;
                    }
                    
                    if (currentUser.getStatus() == 3) {
                        log.warn("用户ID {} 已被删除，拒绝访问", authID);
                        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                        return false;
                    }

                    // 将用户id设置到当前线程中
                    CurrentHolderUtil.setCurrentId(authID);

                    // 角色权限校验
                    if (!checkRolePermission(uri, authRole)) {
                        log.warn("用户角色[{}]无权访问路径[{}]", authRole, uri);
                        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                        return false;
                    }

                    return true;
                } else {
                    log.warn("Token验证失败: token无效");
                }
            } catch (Exception e) {
                log.error("Token验证异常: {}", e.getMessage(), e);
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                return false;
            }
        } else {
            log.warn("请求头中没有token或token为空");
        }

        // 如果没有token或验证失败，返回401状态码
        log.warn("身份验证失败，返回401状态码");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }

    /**
     * 检查用户角色是否有权限访问该路径
     * @param uri 请求路径
     * @param userRole 用户角色
     * @return 是否有权限
     */
    private boolean checkRolePermission(String uri, String userRole) {
        // 通用路径，所有角色都可以访问
        if (uri.startsWith("/api/users/")) {
            return true;
        }

        // 患者角色权限控制
        if ("USER".equals(userRole)) {
            return uri.startsWith("/api/user");
        }

        // 医生角色权限控制
        if ("STAFF".equals(userRole)) {
            return uri.startsWith("/api/staff");
        }


        // 管理员角色权限控制
        if ("ADMIN".equals(userRole)) {
            return uri.startsWith("/api/admin");
        }

        // 默认不允许访问
        return false;
    }


    /**
     * 在请求处理完成后进行清理
     * @param request 请求对象
     * @param response 响应对象
     * @param handler 处理器
     * @param ex 异常
     * @throws Exception 异常
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求结束后，清理ThreadLocal资源，防止内存泄漏
        CurrentHolderUtil.remove();
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }


}
